﻿using Caliburn.Micro;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using SD.Infrastructure.WPF.Models;
using SD.IOC.Core.Mediators;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using SlamDunk.MES.Client.ViewModels.Facility;
using SlamDunk.MES.IAppService.DTOs.Outputs.QualityContext;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation.Models;
using SlamDunk.MES.Presentation.Models.NotifyModels;

namespace SlamDunk.MES.Client.ViewModels.Report
{
    /// <summary>
    /// 成品质检统计ViewModel
    /// </summary>
    public class ExecutionPlanInspectionReportViewModel : ScreenBase
    {
        #region # 字段及构造器
        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IResourceContract> _resourceContract;

        /// <summary>
        /// 质量管理服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IQualityContract> _iQualityContract;

        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IResourceContract> _iResourceContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;

        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public ExecutionPlanInspectionReportViewModel(ServiceProxy<IResourceContract> resourceContract, ServiceProxy<IQualityContract> iQualityContract, ServiceProxy<IResourceContract> iResourceContract, IWindowManager windowManager)
        {
            this._resourceContract = resourceContract;
            this._iQualityContract = iQualityContract;
            this._windowManager = windowManager;
            this._iResourceContract = iResourceContract;
        }
        #endregion

        #region # 属性

        #region 开始时间 —— DateTime? StartTime
        /// <summary>
        /// 开始时间
        /// </summary>
        [DependencyProperty]
        public DateTime? StartTime { get; set; }
        #endregion

        #region 结束时间 —— DateTime? EndTime
        /// <summary>
        /// 结束时间
        /// </summary>
        [DependencyProperty]
        public DateTime? EndTime { get; set; }
        #endregion

        #region 物料定义
        /// <summary>
        /// 物料定义
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialInfo> Materials { get; set; }
        #endregion

        #region 已选物料定义
        /// <summary>
        /// 已选物料定义
        /// </summary>
        [DependencyProperty]
        public MaterialInfo SelectedMaterial { get; set; }
        #endregion

        #region 成品质检统计列表 —— ExecutionPlanInspectionReportList
        /// <summary>
        /// 成品质检统计列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<ExecutionPlanInspectionSummaryNm> ExecutionPlanInspectionReportList { get; set; }
        #endregion

        #endregion

        #region # 方法

        //Initializations

        #region 初始化 —— override async Task OnInitializeAsync(CancellationToken cancellationToken)
        /// <summary>
        /// 初始化
        /// </summary>
        protected override async Task OnInitializeAsync(CancellationToken cancellationToken)
        {
            PageModel<MaterialInfo> materials = await Task.Run(() => this._iResourceContract.Channel.GetMaterialsByPage(
                  null,//关键字
                  null,//物料来源类型
                  null,//是否按批量管理
                  null,//工厂模型Id
                  true,//是否启用
                  null,//物料类Id
                  1,
                  int.MaxValue));
            Materials = new ObservableCollection<MaterialInfo>(materials.Datas);

            StartTime = DateTime.Now.AddDays(-30);
            EndTime = DateTime.Now;
            await this.ReloadExecutionPlanInspectionReports();
        }
        #endregion

        //Actions

        #region 查看物料产出统计 —— async void LoadMaterialSummaryReport()
        /// <summary>
        /// 查看物料产出统计
        /// </summary>
        public async void LoadExecutionPlanInspectionReport()
        {
            await this.ReloadExecutionPlanInspectionReports();
        }
        #endregion

        #region 查看明细
        /// <summary>
        /// 查看明细
        /// </summary>
        public async void LookExecutionPlanInspectionReport(ExecutionPlanInspectionSummaryNm executionPlanInspectionSummaryNm)
        {
            this.Busy();
            ExecutionPlanInspectionDetailReportViewModel viewModel = ResolveMediator.Resolve<ExecutionPlanInspectionDetailReportViewModel>();
            viewModel.Load(executionPlanInspectionSummaryNm);
            bool? result = await this._windowManager.ShowDialogAsync(viewModel);
            this.Idle();
        }
        #endregion 
        //Private

        #region 加载成品统计列表 —— async Task ReloadExecutionPlanInspectionReports()
        /// <summary>
        /// 加载成品统计列表
        /// </summary>
        private async Task ReloadExecutionPlanInspectionReports()
        {
            ExecutionPlanInspectionReportList = new ObservableCollection<ExecutionPlanInspectionSummaryNm>();
            this.Busy();
            DateTime? startTime = this.StartTime;
            DateTime? endTime = this.EndTime;
            //获取作业计划质量检查列表
            PageModel<ExecutionPlanInspectionInfo> pageModel = await Task.Run(() => this._iQualityContract.Channel.GetExecutionPlanInspectionsByPage(
                null,//关键字
                null, //作业计划Id
                null, //审核状态
                startTime,//开始时间
                endTime, //结束时间
                1, //页码
                int.MaxValue));
            foreach (var executionPlanInspectionInfo in pageModel.Datas)
            {
                //获取质量检查明细列表
                IEnumerable<QualityInspectionDetailInfo> qualityInspectionDetails = this._iQualityContract.Channel.GetQualityInspectionDetails(executionPlanInspectionInfo.Id);
                foreach (var qualityInspectionDetailInfo in qualityInspectionDetails)
                {
                    //查询集合中是否存在重复产品
                    ExecutionPlanInspectionSummaryNm executionPlanInspectionReport = ExecutionPlanInspectionReportList.SingleOrDefault(x => x.MaterialId == qualityInspectionDetailInfo.ProductId);
                    if (executionPlanInspectionReport == null)
                    {
                        ExecutionPlanInspectionSummaryNm executionPlanInspectionSummaryNm = new ExecutionPlanInspectionSummaryNm();
                        executionPlanInspectionSummaryNm.MaterialId = qualityInspectionDetailInfo.ProductId;
                        executionPlanInspectionSummaryNm.MaterialNo = qualityInspectionDetailInfo.ProductInfo?.Number;
                        executionPlanInspectionSummaryNm.MaterialName = qualityInspectionDetailInfo.ProductInfo?.Name;
                        executionPlanInspectionSummaryNm.ProductionQuantity = qualityInspectionDetailInfo.ProductionQuantity;
                        executionPlanInspectionSummaryNm.SampleQuantity = qualityInspectionDetailInfo.SampleQuantity;
                        executionPlanInspectionSummaryNm.Manhour = qualityInspectionDetailInfo.Manhour;
                        executionPlanInspectionSummaryNm.Machinehour = qualityInspectionDetailInfo.Machinehour;
                        executionPlanInspectionSummaryNm.PlanStartTime = StartTime;
                        executionPlanInspectionSummaryNm.PlanEndTime = EndTime;
                        executionPlanInspectionSummaryNm.QualifiedRate = (executionPlanInspectionSummaryNm.QualifiedQuantity / executionPlanInspectionSummaryNm.ProductionQuantity);
                        //明细
                        ObservableCollection<ExecutionPlanInspectionSummaryDetailNm> executionPlanInspectionDetailReportInfos = new ObservableCollection<ExecutionPlanInspectionSummaryDetailNm>();
                        ExecutionPlanInspectionSummaryDetailNm executionPlanInspectionSummaryDetailNm = new ExecutionPlanInspectionSummaryDetailNm();
                        executionPlanInspectionSummaryDetailNm.MaterialNo = qualityInspectionDetailInfo.ProductInfo?.Number;
                        executionPlanInspectionSummaryDetailNm.MaterialName = qualityInspectionDetailInfo.ProductInfo?.Name;
                        executionPlanInspectionSummaryDetailNm.TestNumber = executionPlanInspectionInfo.Number;
                        executionPlanInspectionSummaryDetailNm.TestName = executionPlanInspectionInfo.Name;
                        executionPlanInspectionSummaryDetailNm.ExecutionPlanNumber = executionPlanInspectionInfo.ExecutionPlanInfo?.Number;
                        executionPlanInspectionSummaryDetailNm.ExecutionPlanName = executionPlanInspectionInfo.ExecutionPlanInfo?.Name;
                        executionPlanInspectionSummaryDetailNm.InspectedDate = executionPlanInspectionInfo.InspectedDate;
                        executionPlanInspectionSummaryDetailNm.CheckStatus = executionPlanInspectionInfo.CheckStatus;
                        executionPlanInspectionDetailReportInfos.Add(executionPlanInspectionSummaryDetailNm);
                        executionPlanInspectionSummaryNm.ExecutionPlanInspectionDetailReports = executionPlanInspectionDetailReportInfos;
                        ExecutionPlanInspectionReportList.Add(executionPlanInspectionSummaryNm);
                    }
                    else
                    {
                        int index = ExecutionPlanInspectionReportList.IndexOf(executionPlanInspectionReport);
                        ExecutionPlanInspectionReportList.Remove(executionPlanInspectionReport);
                        executionPlanInspectionReport.ProductionQuantity += executionPlanInspectionReport.ProductionQuantity;
                        executionPlanInspectionReport.QualifiedQuantity += executionPlanInspectionReport.QualifiedQuantity;
                        executionPlanInspectionReport.SampleQuantity += executionPlanInspectionReport.SampleQuantity;
                        executionPlanInspectionReport.Manhour += executionPlanInspectionReport.Manhour;
                        executionPlanInspectionReport.Machinehour += executionPlanInspectionReport.Machinehour;
                        executionPlanInspectionReport.QualifiedRate = (executionPlanInspectionReport.QualifiedQuantity / executionPlanInspectionReport.ProductionQuantity);
                        executionPlanInspectionReport.PlanStartTime = StartTime;
                        executionPlanInspectionReport.PlanEndTime = EndTime;

                        //明细
                        ExecutionPlanInspectionSummaryDetailNm executionPlanInspectionSummaryDetailNm = new ExecutionPlanInspectionSummaryDetailNm();
                        executionPlanInspectionSummaryDetailNm.MaterialNo = qualityInspectionDetailInfo.ProductInfo?.Number;
                        executionPlanInspectionSummaryDetailNm.MaterialName = qualityInspectionDetailInfo.ProductInfo?.Name;
                        executionPlanInspectionSummaryDetailNm.TestNumber = executionPlanInspectionInfo.Number;
                        executionPlanInspectionSummaryDetailNm.TestName = executionPlanInspectionInfo.Name;
                        executionPlanInspectionSummaryDetailNm.ExecutionPlanNumber = executionPlanInspectionInfo.ExecutionPlanInfo?.Number;
                        executionPlanInspectionSummaryDetailNm.ExecutionPlanName = executionPlanInspectionInfo.ExecutionPlanInfo?.Name;
                        executionPlanInspectionSummaryDetailNm.InspectedDate = executionPlanInspectionInfo.InspectedDate;
                        executionPlanInspectionSummaryDetailNm.CheckStatus = executionPlanInspectionInfo.CheckStatus;
                        executionPlanInspectionReport.ExecutionPlanInspectionDetailReports.Add(executionPlanInspectionSummaryDetailNm);
                        this.ExecutionPlanInspectionReportList.Insert(index, executionPlanInspectionReport);
                    }
                }
            }
            if (SelectedMaterial != null)
            {
                ExecutionPlanInspectionReportList = new ObservableCollection<ExecutionPlanInspectionSummaryNm>(ExecutionPlanInspectionReportList.Where(x => x.MaterialId == SelectedMaterial.Id));
            }
            this.Idle();
        }
        #endregion
        #endregion
    }
}
